import { AudioClip, Component, tween, Tween } from "cc";

import { AudioMusic } from "./AudioMusic";
import { AudioEffect } from "./AudioEffect";

export class AudioManager extends Component {
    private music: AudioMusic = null!;
    private effect: AudioEffect = null!;

    private _volumeMusic: number = 1;  // 背景音乐音量值
    public get volumeMusic(): number { return this._volumeMusic; }
    public set volumeMusic(value: number) {
        this._volumeMusic = value;
        this.music.volume = value;
    }

    private _volumeEffect: number = 1;  // 音效音量值
    public get volumeEffect(): number { return this._volumeEffect; }
    public set volumeEffect(value: number) {
        this._volumeEffect = value;
        this.effect.volume = value;
    }

    private _switchMusic: boolean = true;  // 背景音乐播放开关
    public get switchMusic(): boolean { return this._switchMusic; }
    public set switchMusic(value: boolean) {
        this._switchMusic = value;

        if (value == false)
            this.music.stop();
    }

    private _switchEffect: boolean = true;  // 音效果播放开关
    public get switchEffect(): boolean { return this._switchEffect; }
    public set switchEffect(value: boolean) {
        this._switchEffect = value;
        if (value == false) this.effect.stop();
    }

    /**
     * 设置背景音乐播放完成回调
     * @param callback 背景音乐播放完成回调
     */
    public setMusicComplete(callback: Function | null = null): void {
        this.music.onComplete = callback;
    }

    /**
     * 播放背景音乐
     * @param url        资源地址
     * @param callback   音乐播放完成事件
     */
    public playMusic(url: string, callback?: Function, bundleName?: string): void {
        if (this._switchMusic) {
            this.music.loop = false;
            this.music.load(url, callback, bundleName);
            this.resetMusicVolume();
        }
    }

    /**
     * 循环播放背景音乐
     * @param url 
     * @param bundleName 
     */
    public playMusicLoop(url: string, bundleName?: string): void {
        if (this._switchMusic) {
            this.music.loop = true;
            this.music.load(url, null!, bundleName);
            this.resetMusicVolume();
        }
    }

    /**
     * 停止背景音乐播放
     */
    public stopMusic(): void {
        if (this._switchMusic && this.music.playing) {
            this.music.stop();
        }
    }

    /**
     * 获取背景音乐播放进度
     */
    public get progressMusic(): number {
        return this.music.progress;
    }

    /**
     * 设置背景乐播放进度
     * @param value     播放进度值
     */
    public set progressMusic(value: number) {
        this.music.progress = value;
    }

    /**
     * 播放音效
     * @param url        资源地址
     */
    public playEffect(url: string | AudioClip, callback?: Function, bundleName?: string): void {
        if (this._switchEffect) {
            this.effect.load(url, callback, bundleName);
        }
    }

    public stopAllEffect(): void {
        if (this.effect.playing) this.effect.stop();
    }

    /** 释放音效资源 */
    public releaseEffect(url: string | AudioClip, bundleName?: string): void {
        this.effect.release(url, bundleName);
    }

    /** 恢复当前暂停的音乐与音效播放 */
    public resumeAll(): void {
        if (this.music) {
            if (!this.music.playing && this.music.progress > 0) this.music.play();
            if (!this.effect.playing && this.effect.progress > 0) this.effect.play();
        }
    }

    /** 暂停当前音乐与音效的播放 */
    public pauseAll(): void {
        if (this.music) {
            if (this.music.playing) this.music.pause();
            if (this.effect.playing) this.effect.pause();
        }
    }

    /** 停止当前音乐与音效的播放 */
    public stopAll(): void {
        if (this.music) {
            this.music.stop();
            this.effect.stop();
        }
    }

    /** 本地加载音乐音效的音量、开关配置数据并设置到游戏中 */
    public load(): void {
        this.music = this.getComponent(AudioMusic) || this.addComponent(AudioMusic)!;
        this.effect = this.getComponent(AudioEffect) || this.addComponent(AudioEffect)!;

        this.setStateDefault();

        if (this.music) this.music.volume = this._volumeMusic;
        if (this.effect) this.effect.volume = this._volumeEffect;
    }

    private setStateDefault() {
        this._volumeMusic = 1;
        this._volumeEffect = 1;
        this._switchMusic = true;
        this._switchEffect = true;
    }

    private _musicVolume = { volume: 1.0 };
    private _fadeTween: Tween<object>;

    public get musicVolume() {
        return this._musicVolume.volume;
    }

    public musicFadeTo(value: number, duration: number): Tween<object> {
        if (this._fadeTween) this._fadeTween.stop();
        this._fadeTween = tween(this._musicVolume).to(duration, { volume: value }, {
            onUpdate: (target, progress) => {
                this.music.volume = target["volume"];
            }
        }).start();
        return this._fadeTween;
    }

    public resetMusicVolume(): void {
        if (this._fadeTween) this._fadeTween.stop();
        this.music.volume = 1;
    }
}

// 创建时间：2025-06-11
// 作者：Alonc
// 用途：音频控制器单例类，实现全局音频管理